﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using app.Models;
using AmuTools;
using System.IO;
using System.Security.Cryptography;
using System.Web.Security;

namespace app.Api
{
    /*
        数据库的初始化，备份等操作

        初始化的目的是保证一些必要的数据添加到数据库中，甚至可以自动建立表（通过执行sql文件代码）等
    */
    public class ApiUpload : ApiBase
    {
        public ApiUpload(Controller ctx) : base(ctx) { }

        private string root_path = "/Resources/";

        #region 自定义请求参数
        // 作者
        string req_author { get { return GetStringParam(new ReqStringParamOption { Name = "author", Level = REQPARAMLEVEL.FREE }); } }

        #endregion

        public void Do(string action)
        {
            switch (action)
            {
                case "file":
                    List<UploadedFile> ulfs = UploadFile(UPLOAD_TYPE.File);
                    ResponseJson(new ListResult<UploadedFile> { list = ulfs });
                    break;
                case "delete": {
                        UploadedFile ulf = G.DB.GetById<UploadedFile>(req_id);
                        G.DB.Delete<UploadedFile>(req_id);
                        DeleteFile(ulf.url);
                        ResponseJson(new Result());
                    } break;
                default: break;
            }
        }
        

        public static string[] image_format = { ".jpg", ".gif", ".bmp", ".png" };
        public static string[] video_format = { ".mp4", ".ogg", ".wmv", ".flv" };
        public static string[] document_format = { ".txt", ".doc", ".docx" };
        public static string[] audio_format = { ".mp3" };
        public static string[] file_format = { ".jpg", ".gif", ".bmp", ".png", ".mp4", ".ogg", ".txt", ".doc", ".docx", ".mp3", ".zip", ".wmv", ".flv" };
        
        private List<UploadedFile> UploadFile(UPLOAD_TYPE ut)
        {
            List<UploadedFile> upload_list = new List<UploadedFile>();
            HttpFileCollectionBase files = ctx.Request.Files;
            int file_count = files.Count;
            if (file_count == 0) return upload_list;
            
            for (int i = 0; i < file_count; i++)
            {
                upload_list.Add(SaveFile(files[i], ut));
            }

            return upload_list;
        }

        private UploadedFile SaveFile(HttpPostedFileBase hpf, UPLOAD_TYPE ut)
        {
            string file_extension = Path.GetExtension(hpf.FileName).ToLower(); // 得到扩展名
            if (!IsValidFormat(file_extension, ut)) return null; // 检测是不是合法类型

            string new_path = GetUploadPath() + CreatePasswordHash(hpf.FileName, 4) + file_extension; // 生成新的路径

            // 先存到数据库
            UploadedFile ulf = new UploadedFile { url = new_path, create_time = DateTimeEx.GetNowTimeStamp(), size = hpf.ContentLength, name = hpf.FileName, person_id = UserCode };
            G.DB.Insert<UploadedFile>(ulf);
            // 再存到本地
            string full_new_path = AppDomain.CurrentDomain.BaseDirectory + new_path;//转换成服务器上的物理路径，用来保存
            hpf.SaveAs(full_new_path); // 保存图片

            return ulf;
        }

        public void DeleteFile(string path)
        {
            string full_path = AppDomain.CurrentDomain.BaseDirectory + path;
            if (File.Exists(full_path))
            {
                File.Delete(full_path);
            }
        }

        /// <summary>
        /// 验证是否指定的图片格式
        /// </summary>
        /// <returns></returns>
        private static bool IsValidFormat(string str, UPLOAD_TYPE upload_type)
        {
            if (upload_type == UPLOAD_TYPE.All) return true;

            string[] format_arr = new string[0];
            switch (upload_type)
            {
                case UPLOAD_TYPE.Image: format_arr = image_format; break;
                case UPLOAD_TYPE.Video: format_arr = video_format; break;
                case UPLOAD_TYPE.Doucment: format_arr = document_format; break;
                case UPLOAD_TYPE.Audio: format_arr = audio_format; break;
                case UPLOAD_TYPE.File: format_arr = file_format; break;
            }

            string thestr = str.ToLower();
            for (int i = 0; i < format_arr.Length; i++)
            {
                if (thestr == format_arr[i]) return true;
            }
            return false;
        }

        private string GetUploadPath()
        {
            DateTime now = DateTime.Now;
            string time_path = now.Year.ToString() + "/" + now.Month.ToString() + "-" + now.Day.ToString() + "/";

            string con_path = root_path + time_path;
            string full_con_path = AppDomain.CurrentDomain.BaseDirectory + con_path;

            if (!Directory.Exists(full_con_path))
            {
                Directory.CreateDirectory(full_con_path);
            }

            return con_path;
        }

        /// <summary>
        /// 创建一个指定长度的随机salt值
        /// </summary>
        private static string CreateSalt(int saltLenght)
        {
            //生成一个加密的随机数
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            byte[] buff = new byte[saltLenght];
            rng.GetBytes(buff);
            //返回一个Base64随机数的字符串
            return Convert.ToBase64String(buff);
        }

        /// <summary>
        /// 返回加密后的字符串
        /// </summary>
        private static string CreatePasswordHash(string pwd, int saltLenght)
        {
            string strSalt = CreateSalt(saltLenght);
            //把密码和Salt连起来
            string saltAndPwd = String.Concat(pwd, strSalt);
            //对密码进行哈希
            string hashenPwd = FormsAuthentication.HashPasswordForStoringInConfigFile(saltAndPwd, "sha1");
            //转为小写字符并截取前16个字符串
            hashenPwd = hashenPwd.ToLower().Substring(0, 16);
            //返回哈希后的值
            return hashenPwd;
        }
    }

    enum UPLOAD_TYPE
    {
        All = 0, // 所有
        Image = 1, // 图片
        Video = 2, // 视频
        Doucment = 3, // 文档
        Audio = 4, // 音频
        File = 5
    }

}